﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Reflection;
using Unknown.Framework.Configuration;
using Unknown.Framework.Develop;
using Unknown.Framework.Injection;

namespace Unknown.Framework.Database
{
    /// <summary>
    /// 实例配置处理类
    /// </summary>
    public class InstanceConfigurationHandler : AbstractConfigurationHandler<Collection<InstanceConfiguration>>
    {
        private Dictionary<string, InstanceIdentify> _Dictionary = new Dictionary<string, InstanceIdentify>();
        /// <summary>
        /// 字典
        /// </summary>
        public Dictionary<string, InstanceIdentify> Dictionary
        {
            get
            {
                return this._Dictionary;
            }
        }

        /// <summary>
        /// 匹配字符串
        /// </summary>
        protected override string SearchPattern
        {
            get
            {
                return ".Database.xml";
            }
        }
        /// <summary>
        /// 示例值
        /// </summary>
        protected override Collection<InstanceConfiguration> ExampleValue
        {
            get
            {
                Collection<InstanceConfiguration> results = new Collection<InstanceConfiguration>();

                InstanceConfiguration instanceConfiguration = new InstanceConfiguration();
                Type sqlConnectionType = typeof(SqlConnection);
                Type sqlDbTypeType = typeof(SqlDbType);
                instanceConfiguration.Name = "Example";
                instanceConfiguration.Source = "Data Source=localhost;Initial Catalog=database;User ID=userId;Password=password";
                instanceConfiguration.Connection = sqlConnectionType.FullName;
                instanceConfiguration.TypeProperty = "SqlDbType";
                instanceConfiguration.TypeEnum = sqlDbTypeType.FullName;

                results.Add(instanceConfiguration);

                return results;
            }
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="value">数据</param>
        protected override void Resolve(Collection<InstanceConfiguration> value)
        {
            if (value != null)
            {
                foreach (InstanceConfiguration instanceConfiguration in value)
                {
                    bool register = this.Dictionary.ContainsKey(instanceConfiguration.Name);
                    if (!register)
                    {
                        DbConnection connection = ObjectFactory.Build(instanceConfiguration.Connection) as DbConnection;

                        object typeEnum = ObjectFactory.Build(instanceConfiguration.TypeEnum);

                        InstanceIdentify instanceIdentify = new InstanceIdentify();

                        if (connection != null)
                        {
                            instanceIdentify.Source = instanceConfiguration.Source;
                            instanceIdentify.Connection = instanceConfiguration.Connection;

                            DbCommand command = connection.CreateCommand();
                            DbParameter parameter = command.CreateParameter();
                            Type parameterType = parameter.GetType();
                            try
                            {
                                instanceIdentify.TypeProperty = parameterType.GetProperty(instanceConfiguration.TypeProperty);
                            }
                            catch (AmbiguousMatchException exception)
                            {
                                Collection<string> remarks = new Collection<string>();
                                remarks.Add(parameterType.FullName);
                                remarks.Add(instanceConfiguration.TypeProperty);

                                CrashHandlers.Default.Hibernate(exception, remarks);
                            }
                            catch (ArgumentNullException exception)
                            {
                                Collection<string> remarks = new Collection<string>();
                                remarks.Add(parameterType.FullName);
                                remarks.Add(instanceConfiguration.TypeProperty);

                                CrashHandlers.Default.Hibernate(exception, remarks);
                            }
                        }
                        if (typeEnum != null)
                        {
                            instanceIdentify.TypeEnum = typeEnum.GetType();
                        }

                        if ((!string.IsNullOrEmpty(instanceIdentify.Connection)) && (!string.IsNullOrEmpty(instanceIdentify.Source)) && (instanceIdentify.TypeProperty != null) && (instanceIdentify.TypeEnum != null))
                        {
                            this.Dictionary.Add(instanceConfiguration.Name, instanceIdentify);
                        }
                    }
                }
            }
        }
    }
}
